﻿using System;
using System.Linq.Expressions;
using System.Threading.Tasks;
using Phoenix.Frames;
using Phoenix.Framework;

namespace Phoenix.ActionResults
{
    public class RedirectActionResult : ActionResult, IHaveInvokeCompletedSteps
    {
        readonly Func<Task> task;

        public RedirectActionResult(ControllerActionContext context, ControllerAction controllerAction, params object[] parameters)
            : base(context)
        {
            task = () => new InvokeActionBuilder(context).InvokeAction(controllerAction, parameters);
        }

        public RedirectActionResult(ControllerActionContext context, string controller, Expression<Func<ActionResult>> action)
            : base(context)
        {
            task = () =>
                       {
                           var controllerActions = new InvokeActionBuilder(context);
                           return controllerActions.InvokeExpression(controller, 
                               controllerActions.GetExpressionFrom(action), 
                               context.ControllerAction.Assembly);
                       };
        }

        public RedirectActionResult(ControllerActionContext context, string controller, Expression<Func<Task<ActionResult>>> action)
            : base(context)
        {
            task = () =>
                       {
                           var controllerActions = new InvokeActionBuilder(context);
                           return controllerActions.InvokeExpression(controller, 
                               controllerActions.GetExpressionFrom(action),
                               context.ControllerAction.Assembly);
                       };
        }

        protected RedirectActionResult(Func<Task> task, ControllerActionContext context) : base(context)
        {
            this.task = task;
        }

        public override void Execute(IContentFrame targetFrame)
        {
        }

        public void InvokeComplete()
        {
            task();
        }
    }
}